﻿using System;
using Castle.MicroKernel;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System.Reflection;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using Castle.Core.Internal;
using System.IO;
using Castle.Facilities.Startable;

namespace Inovout
{
    public partial class ComponentRegistry
    {
        private IWindsorContainer container = new WindsorContainer();

        internal IWindsorContainer Container
        {
            get { return container; }
        }
        private List<ComponentAssembly> componentAssemblys = new List<ComponentAssembly>();

        private AppDomain appDomain;

        //private List<ComponentInstaller> componentRegistrations = new List<ComponentInstaller>();
        //protected internal void AddComponentRegistration(ComponentInstaller componentRegistration)
        //{
        //    componentRegistrations.Add(componentRegistration);
        //}
        private ComponentRegistry(AppDomain appDomain,IApplication application)
        {
            this.appDomain = appDomain;
            Init(application);
        }

        private void Init(IApplication application)
        {
            container.Register(Component.For<IApplication>().Instance(application));
            container.AddFacility<StartableFacility>(f => f.DeferredStart());

            IAssemblyProvider frameworkAssemblyProvider = new AssemblyFilter(
              Path.GetDirectoryName(new Uri(typeof(ComponentRegistry).Assembly.CodeBase).LocalPath)).WithKeyToken(typeof(ComponentRegistry).Assembly.GetName().GetPublicKeyToken());
            IEnumerable<Assembly> frameworkAssemblies = frameworkAssemblyProvider.GetAssemblies();
            foreach (Assembly frameworkAssembly in frameworkAssemblies)
            {
                AddComponentAssembly(frameworkAssembly);
            }
            //IAssemblyProvider moduleAssemblyProvider = new AssemblyFilter(
            //    Path.GetDirectoryName(Path.Combine(appDomain.BaseDirectory,"bin")));
            IEnumerable<Assembly> moduleAssemblies = appDomain.GetAssemblies().Except(frameworkAssemblies);
            foreach (Assembly assembly in moduleAssemblies)
            {
                AddComponentAssembly(assembly);
            }
            appDomain.AssemblyLoad += new AssemblyLoadEventHandler(AssemblyLoadHandler);
        }

        private void AddComponentAssembly(Assembly assembly)
        {
            ComponentAssembly componentAssembly = new ComponentAssembly(this, assembly);
            componentAssembly.Load();
            componentAssemblys.Add(componentAssembly);
        }
        private void AssemblyLoadHandler(object sender, AssemblyLoadEventArgs args)
        {
            if (!args.LoadedAssembly.IsDynamic)
            {
                AddComponentAssembly(args.LoadedAssembly);
            }
        }











    }

}
